#include "rtdev.h"
#include "rtbus/rtbus.h"
#include "log/zuclog.h"
#include "config.h"
#include "safetyboard/scbitf.h"
#include "rtdev/rtrobot.h"
#include "hwdrv/hwdrv.h"
// #include "safetyboard_intf.h"
// #include "tio.h"
// #include "bpcontrolhandle.h"

#define RTDEV_DEBUG(fmt, ...) zuclog_debug("RTDEV", fmt, ##__VA_ARGS__)
#define RTDEV_INFO(fmt, ...) zuclog_info("RTDEV", fmt, ##__VA_ARGS__)
#define RTDEV_ERR(fmt, ...) zuclog_error("RTDEV", fmt, ##__VA_ARGS__)

using namespace rtdev;
static const uint8_t DEFAULT_SIM_CAB = kScbTypeMaxcab;

int RtDevMgr::init_cab_bp()
{
    auto scbinfo = hwdrv::HwMgr::get().get_scb_slot();
    auto dev = SafetyBoardItf::create(scbinfo.type);
    if (!dev)
    {
        //不成功则创建一个默认的仿真模式的机柜
        dev = SafetyBoardItf::create(DEFAULT_SIM_CAB);
        dev->init(nullptr, true);
    }
    else
    {
        dev->init(nullptr, hwdrv::HwMgr::get().is_sim());
    }

    scb_.reset(dev);

    int err = scb_->boot();
    RTDEV_INFO("SCB %s boot %s", scb_->name(), err ? "failed" : "success");

    //TODO: 手柄初始化
    RTDEV_INFO("BP boot %s", scb_->name(), err ? "failed" : "success");
    return 0;
}

static const char* get_dev_name(rtdev::RtDevType type)
{
    switch (type)
    {
    case rtdev::DEV_BP_HANDLE:
        return "BP Handle";
    case rtdev::DEV_SAFETY_BOARD:
        return "Safety Board";
    case rtdev::DEV_TIO:
        return "TIO";
    default:
        return "Unknown";
    }
}
// rtdev::RtDevItf::RtDevItf() {}
// int rtdev::RtDevItf::keep_alive(int alive) { return 0; }
// bool rtdev::RtDevItf::is_alive() { return false; }
// bool rtdev::RtDevItf::is_sim() { return false; }
rtdev::RtDev::RtDev(RtDevType type) : type_(type) { alive_watchdog_ = 0; }

rtdev::RtDev::~RtDev() {}

void rtdev::RtDev::init() {}

void rtdev::RtDev::update()
{
    if (sim_flag_)
    {
        alive_flag_ = true;
        return;
    }
    check_alive();
}

void rtdev::RtDev::check_alive()
{
    bool alive = false;
    if (sim_flag_)
    {
        alive = true;
    }
    else
    {
        if (alive_watchdog_ <= 0)
        {
            alive = false;
        }
        else
        {
            alive_watchdog_--;
            alive = true;
        }
    }
    if (alive != alive_flag_)
    {
        if (alive)
        {
            RTDEV_DEBUG("Device: %s is online, sim=%d", get_dev_name(type_), sim_flag_);
            action_when_online();
        }
        else
        {
            RTDEV_DEBUG("Device: %s is offline, sim=%d", get_dev_name(type_), sim_flag_);
            action_when_offline();
        }
        alive_flag_ = alive;
    }
}

void rtdev::device_update(double ts)
{
    // // 手柄
    // rtdev::get_bp_handle()->update();

    // scb
    auto s = rtdev::RtDevMgr::instance().get_scb();
    if (s)
    {
        s->get_recv_data();
        s->set_send_data();
    }
}